from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.request import Request
from utils.base import BasePageNumberPagination
from apps.tests.filters import CaseFilter, StepFilter, CaseRunLogsFilter, TagFilter
from apps.tests.models import Case, Step, CaseRunLog, Tag
from apps.scripts.models import PythonScript
from apps.interfaces.models import Api
from apps.tests.serializers import CaseSerializers, StepSerializers, CaseRunLogsSerializers, TagSerializer
from utils.base_view import BaseModelViewSet
from apps.envs.models import Plant, Module
from core.run_one_case import run_one_case, StepType
from core.check import CHECK_FUNC_MAP
from core.run_step_web_ui import selenium_actions, selenium_func_doc
from core.faker import FAKER_FUNC_MAP, FAKER_FUNC_LIST, FAKER_FUNC_DOC


class CaseViewSet(BaseModelViewSet):
    serializer_class = CaseSerializers
    queryset = Case.objects.all()
    permission_classes = [IsAuthenticated]
    pagination_class = BasePageNumberPagination
    filterset_class = CaseFilter


class TagViewSet(BaseModelViewSet):
    serializer_class = TagSerializer
    queryset = Tag.objects.all()
    permission_classes = [IsAuthenticated]
    pagination_class = BasePageNumberPagination
    filterset_class = TagFilter


class StepViewSet(BaseModelViewSet):
    serializer_class = StepSerializers
    queryset = Step.objects.all()
    permission_classes = [IsAuthenticated]
    pagination_class = BasePageNumberPagination
    filterset_class = StepFilter


class CaseRunLogsViewSet(BaseModelViewSet):
    serializer_class = CaseRunLogsSerializers
    queryset = CaseRunLog.objects.all()
    permission_classes = [IsAuthenticated]
    pagination_class = BasePageNumberPagination
    filterset_class = CaseRunLogsFilter


def get_plant_api_action_keys(project_id):
    plants = Plant.objects.all().filter(project=project_id, is_delete=False).values()
    for plant_obj in plants:
        plant_obj['children'] = Module.objects.all().filter(plant=plant_obj['id'], is_delete=False).values()
        if not plant_obj['children']:
            plant_obj['disabled'] = True
        for module_obj in plant_obj['children']:
            module_obj['children'] = Api.objects.all().filter(module=module_obj['id'], is_delete=False).values()
            if not module_obj['children']:
                module_obj['disabled'] = True
    return plants


def get_plant_step_action_keys(project_id):
    plants = Plant.objects.all().filter(project=project_id, is_delete=False).values()
    for plant_obj in plants:
        plant_obj['children'] = Module.objects.all().filter(plant=plant_obj['id'], is_delete=False).values()
        if not plant_obj['children']:
            plant_obj['disabled'] = True
        for module_obj in plant_obj['children']:
            module_obj['children'] = Step.objects.all().filter(module=module_obj['id'], is_delete=False).values()
            if not module_obj['children']:
                module_obj['disabled'] = True
    return plants


def get_plant_script_action_keys(project_id):
    plants = Plant.objects.all().filter(project=project_id, is_delete=False).values()
    for plant_obj in plants:
        plant_obj['children'] = Module.objects.all().filter(plant=plant_obj['id'], is_delete=False).values()
        if not plant_obj['children']:
            plant_obj['disabled'] = True
        for module_obj in plant_obj['children']:
            module_obj['children'] = PythonScript.objects.all().filter(module=module_obj['id'], is_delete=False).values()
            if not module_obj['children']:
                module_obj['disabled'] = True
    return plants


@api_view(['POST'])
def case_run(request: Request):
    env_id = request.data.get('env_id')
    case_id = request.data.get('case_id')
    #case_name = run_one_case.delay(env_id, case_id, request.user.id)
    case_name = run_one_case(env_id, case_id, request.user.id)
    return Response(data=f'【{case_name}】 执行中', status=200)


@api_view(['GET'])
def get_check_list(request: Request):
    return Response(data=[function_name for function_name in CHECK_FUNC_MAP.keys() if
                          function_name.startswith('check')], status=200)


@api_view(['GET'])
def get_func_params(request: Request):
    step_type = request.query_params.get('step_type')
    data = FAKER_FUNC_DOC if step_type == StepType.FUNCTION else selenium_func_doc
    return Response(data=data, status=200)


@api_view(['GET'])
def action_keys(request: Request):
    project_id = request.query_params.get('project')
    plant_apis = get_plant_api_action_keys(project_id)
    plant_scripts = get_plant_script_action_keys(project_id)
    data = [
        {
            "name": 'functions',
            "id": StepType.FUNCTION,
            "children": FAKER_FUNC_LIST
        },
        {
            "name": 'requests',
            "id": StepType.API,
            "children": plant_apis
        },
        {
            "name": 'scripts',
            "id": StepType.SCRIPT,
            "children": plant_scripts
        },
        {
            "name": 'selenium',
            "id": StepType.UI,
            "children": selenium_actions
        },
    ]
    if request.query_params.get('isCase'):
        plant_steps = get_plant_step_action_keys(project_id)
        data.append({
            "name": 'steps',
            "id": StepType.STEP,
            "children": plant_steps
        })
    return Response(data=data, status=200)


